﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;

namespace EcoSystem
{
    public class DictionaryAppService : CrudAppService<
        DictionaryItem,
        DictionaryItemDto,
        Guid,
        GetDictionaryItemInput,
        CreateOrUpdateDictionaryItemDto,
        CreateOrUpdateDictionaryItemDto>, IDictionaryAppService
    {
        private readonly IRepository<DictionaryValue> _valueRepository;
        public DictionaryAppService(IRepository<DictionaryItem, Guid> repository,
            IRepository<DictionaryValue> valueRepository) : base(repository)
        {
            _valueRepository = valueRepository;
        }

        public override async Task<PagedResultDto<DictionaryItemDto>> GetListAsync(GetDictionaryItemInput input)
        {
            var query = (await Repository.GetQueryableAsync()).AsNoTracking();
            query = query.WhereIf(!input.Key.IsNullOrWhiteSpace(), x => x.ModuleCode.Contains(input.Key) || x.Code.Contains(input.Key) || x.Name.Contains(input.Key))
                .WhereIf(!input.ModuleCode.IsNullOrWhiteSpace(), x => x.ModuleCode == input.ModuleCode)
                .WhereIf(input.Status.HasValue, x => x.Status == input.Status);
            var total = await query.CountAsync();
            var items = await query.OrderBy(x => x.Code).PageBy(input).ToListAsync();
            return new PagedResultDto<DictionaryItemDto>()
            {
                Items = await MapToGetListOutputDtosAsync(items),
                TotalCount = total
            };
        }

        public override async Task<DictionaryItemDto> CreateAsync(CreateOrUpdateDictionaryItemDto input)
        {
            var entity = MapToEntity(input);
            EntityHelper.TrySetId(entity, () => GuidGenerator.Create());
            entity.Items?.ForEach(item =>
            {
                EntityHelper.TrySetId(item, () => GuidGenerator.Create());
            });
            await Repository.InsertAsync(entity, true);
            return MapToGetListOutputDto(entity);
        }


        public override async Task<DictionaryItemDto> UpdateAsync(Guid id, CreateOrUpdateDictionaryItemDto input)
        {
            var entity = await Repository.GetAsync(id, includeDetails: true);
            MapToEntity(input, entity);
            entity.Items?.ForEach(item =>
            {
                if (item.Id == Guid.Empty)
                {
                    EntityHelper.TrySetId(item, () => GuidGenerator.Create());
                }
            });
            await Repository.UpdateAsync(entity, true);
            return MapToGetListOutputDto(entity);
        }

        public override async Task<DictionaryItemDto> GetAsync(Guid id)
        {
            var entity = await Repository.GetAsync(id, includeDetails: true);
            return await MapToGetOutputDtoAsync(entity);
        }


        /// <summary>
        /// 获取所有
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<DictionaryItemDto>> GetAllListAsync(GetDictionaryItemInput input)
        {
            var query = (await Repository.GetQueryableAsync()).AsNoTracking();
            query = query.WhereIf(!input.Key.IsNullOrWhiteSpace(), x => x.ModuleCode.Contains(input.Key) || x.Code.Contains(input.Key) || x.Name.Contains(input.Key))
                .WhereIf(!input.ModuleCode.IsNullOrWhiteSpace(), x => x.ModuleCode == input.ModuleCode)
                .WhereIf(input.Status.HasValue, x => x.Status == input.Status);
            var items = await query.OrderBy(x => x.Code).ToListAsync();

            var valueQuery = (await _valueRepository.GetQueryableAsync()).AsNoTracking();
            var valueItems = await valueQuery.ToListAsync();
            items.ForEach(item =>
            {
                item.Items = valueItems.Where(x => x.ItemId == item.Id).OrderBy(x => x.SortIndex).ToList();
            });
            return await MapToGetListOutputDtosAsync(items);
        }

        /// <summary>
        /// 获取字典值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public async Task<List<DictionaryValueDto>> GetValueItemsAsync(string name)
        {
            var id = (await Repository.GetQueryableAsync()).AsNoTracking().Where(x => x.Code == name).Select(x => x.Id).FirstOrDefault();
            var query = await _valueRepository.GetQueryableAsync();
            if (id == Guid.Empty)
            {
                return new List<DictionaryValueDto>();
            }
            var items = await query.Where(x => x.ItemId == id).ToListAsync();
            return ObjectMapper.Map<List<DictionaryValue>, List<DictionaryValueDto>>(items);
        }
    }
}
